home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-12-27 | 6.6 KB | 127 lines | [TEXT/YERK] |
- \ FPI/O -- floating-point I/O support for 68000 SANE engine.
- \ 5/11/85 ssg Version 1.0
- \ 9/26/85 cbd Modified for float heap, removed minor methods
- \ 2/07/86 gdc Added words atof and f.r, changed eprint to eprint, printxyz
- \ 8/16/86 cdn Eliminated finit & Stringer shorten
- \ 5/26/91 rfl Eliminated Stringer class altogether.
- \ 10/26/91 rfl abs in front of /mod
- \ 12/17/92 rfl fixed a few problems that might occur due to not locking handles
- \ 01/26/93 rfl protect parse: to reject a possible float if 2 decimal points are mistakenly
- \ adjacent. The case of " 1.234.56" is interpreted as an integer
- \ 12/03/93 rfl fixed problem with non FPU machines returning garbage exp when
- \ 0 is passed to num2dec in float2dec:. Thanks to Harry Haddon.
- \ Removed 2 bytes scratch -use pad instead. Removed if true else false
- \ 12/05/93 rfl Rewrote much of the formatting routines and added ability to
- \ get addr len of format on stack. More use of pack7 utilities.
-
- Decimal
-
- \ Some useful constants
- 256 constant neg
- 0 constant pos
- 256 constant FixedDecimal
- 0 constant FloatDecimal
- 0 value topxyz \ top of string being converted to float
-
- 0 variable valid? \ used for scan: but never used otherwise...mhore
-
- \ reentrant code to get rid of leading zeros - not used here
- \ : endZ ( addr -- addr) dup c@ ascii 0 = IF 1+ endZ THEN ;
-
- :CLASS FPI/O <Super Object
-
- \ SANE Record Decimal ( x:= (-1)^sgn * 10^exp * SigDig )
- INT sgn \ sign; 0=pos, 256=neg
- INT exp \ as if decimal point were to the right of SigDig
- 22 BYTES SigDig \ to fake string[20] ; 22 to make even
-
- \ SANE Record DecForm
- INT style \ Float=0; Fixed=256
- INT digits \ # of sig digits,if float; # dec. places,if fixed.
-
- string floater \ to hold formatted output string
- string expStr \ to hold formatted exponent string
- var places \ number of places to right of dec. pt.
-
- int index
-
- ( -- )
- :M CLEAR: addr: sgn 26 erase unlock: floater clear: floater clear: expstr ;M
-
- ( -- ) \ Initialize strings etc.
- :M INIT: new: floater new: expStr clear: self ;M
-
- ( -- )
- :M EINIT: clear: self FloatDecimal put: style ( 19 put: digits) ;M
-
- ( -- ) \ Initialize for fixed conversion
- :M FINIT: clear: self FixedDecimal put: style ;M
-
- ( -- ) \ Puts a zero in decimal record
- :M ZERO: clear: self $ 0130 addr: sigDig w! ;M
-
- ( -- float ) \ ==== attempt to convert decimal to a float;
- :M DEC2FLOAT: { \ flt -- flt }
- abs: sgn \ Addr of decimal record
- new: fltMem -> flt flt 2+ +base \ Absolute Destination address
- $ 0009 \ FFEXT FOD2B + -- Opcode for decimal to binary; dest=extended
- fp68k flt \ Call FP68K
- ;M
-
- ( float -- ) \ ==== convert float to decimal ==== \
- :M FLOAT2DEC: { flt -- }
- abs: style \ Absolute Addr of Decform record
- flt 2+ +base \ Absolute Addr of source
- abs: sgn \ Absolute Addr of Decimal record
- $ 000b \ FFEXT FOB2D + -- Opcode for binary to decimal; source=extended
- fp68k flt fdrop \ Call FP68K, dispose of float
- \ addr: sigDig 1+ c@ ascii 0 =
- \ IF clear: exp THEN
- ;M
-
- ( -- ) \ Set up float for in decimal record in scientific format,
- \ left-justified in a field of width characters.
- :M num2dec: float2dec: self
- abs: style (abs) pad +base call dec2str
- pad count put: floater ;M
-
- :M ROUND: ( f -- f') 1 swap 0 do 10 * LOOP >float fdup >r f* round r> f/ ;M
-
- ( flt width -- addr len)
- :M GETEText: { width \ pos -- addr len }
- einit: self
- num2dec: self
- start: floater ascii e charof: floater
- IF drop size: floater substr: floater put: expStr
- width size: expStr - 3 max \ bl or -, digit, decimal minimum
- size: floater size: expStr - min -> pos \ keep at least 2 numbers for decimal
-
- pos moveto: floater \ round up NEED
-
- size: floater substr: floater get: expStr replace: floater
- ELSE addr: sigDig count drop c@
- dup ascii I = IF pad 1+ 1 put: floater
- " Infinity" add: floater
- width 10 - 0 DO bl +: floater LOOP
- THEN
- ascii N = IF pad 1+ 1 put: floater width 14 >
- IF " Not a number " add: floater
- width 14 -
- ELSE " NaN " add: floater
- width 5 -
- THEN
- 0 DO bl +: floater LOOP
- THEN
- THEN lock: floater get: floater ;M
-
- :M EPRINT: geteText: self type ;M
- \ Carry out f.r
- :M GETFText: { width decimal \ dot -- addr len }
- finit: self
- decimal round: self num2dec: self
- start: floater ascii . charof: floater
- IF -> dot
- decimal abs 1+ subStr: floater put: expStr
- get: sgn not IF start: floater bl pad c! pad 1 insert: floater 1 ++> dot THEN
- dot moveto: floater
- size: floater substr: flo